#include"customItem.h"
TopLeftPoint::TopLeftPoint(qreal x,qreal y,QGraphicsItem* item):QGraphicsEllipseItem(-5,-5,10,10),controledItem(item)
{
	this->setPos(x,y);
	this->setBrush(QBrush(QColor(0,0,0)));
	this->setFlag(QGraphicsEllipseItem::ItemIsMovable);
	this->setFlag(QGraphicsItem::ItemIsSelectable);
}
QGraphicsItem* TopLeftPoint::getControlledItem()
{
	return this->controledItem;
}
void TopLeftPoint::mousePressEvent(QGraphicsSceneMouseEvent* event)
	{
		QGraphicsEllipseItem::mousePressEvent(event);
	}
void TopLeftPoint::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
	{
		QPointF p=this->pos();
		QPointF mouse=this->pos();
		mouse=this->controledItem->mapFromScene(mouse);
		QPointF brp=((customRectItem*)(this->controledItem))->brp;;
		double nx=brp.x()-mouse.x();
		double ny=brp.y()-mouse.y();
		if(nx<0.1)
			nx=abs(nx)/nx*1;
		if(ny<0.1)
			ny=abs(ny)/ny;
		double newxscale=(nx)/((customRectItem*)(this->controledItem))->oriWidth;
		double newyscale=(ny)/((customRectItem*)(this->controledItem))->oriHeight;
		//QTrasform trn=((customRectItem*)(this->controledItem))
		QTransform tr0=QTransform(1,0,0,1,mouse.x(),mouse.y());
		QTransform tr=QTransform(newxscale,0,0,newyscale,0,0);
		QTransform tr5=((customRectItem*)(this->controledItem))->scaleTr;
		tr5=tr*tr5;
		this->controledItem->setTransform(tr0,true);
		this->controledItem->setTransform(tr,true);
		((customRectItem*)(this->controledItem))->scaleTr=tr*((customRectItem*)(this->controledItem))->scaleTr;
		((customRectItem*)(this->controledItem))->translationTr=tr0*((customRectItem*)(this->controledItem))->translationTr;
		((customRectItem*)(this->controledItem))->updatePoints();
		QGraphicsEllipseItem::mouseMoveEvent(event);
	}
/******************************************************************************************************************************************/
TopRightPoint::TopRightPoint(qreal x,qreal y,QGraphicsItem* item):QGraphicsEllipseItem(-5,-5,10,10),controledItem(item)
{
	this->setPos(x,y);
	this->setBrush(QBrush(QColor(0,0,0)));
	this->setFlag(QGraphicsEllipseItem::ItemIsMovable);
	this->setFlag(QGraphicsItem::ItemIsSelectable);
}
QGraphicsItem* TopRightPoint::getControlledItem()
{
	return this->controledItem;
}
void TopRightPoint::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
	{
		QGraphicsEllipseItem::mouseDoubleClickEvent(event);
	}
void TopRightPoint::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
	{
		QPointF p=this->pos();
		QPointF mouse=this->pos();
		mouse=this->controledItem->mapFromScene(mouse);
		QPointF bp=this->controledItem->pos();
        double nx=mouse.x();
		double ny=((customRectItem*)(this->controledItem))->blp.y()-mouse.y();
		if(nx<0.1)
			nx=abs(nx)/nx*1;
		if(ny<0.1)
			ny=abs(ny)/ny;
		double newxscale=(nx)/((customRectItem*)(this->controledItem))->oriWidth;
		double newyscale=(ny)*1.0/((customRectItem*)(this->controledItem))->oriHeight;
		QTransform tr0=QTransform(1,0,0,1,0,mouse.y());
		QTransform tr=QTransform(newxscale,0,0,newyscale,0,0);
		this->controledItem->setTransform(tr0,true);
		this->controledItem->setTransform(tr,true);
		//this->parentItem->setScale(newxscale);
		((customRectItem*)(this->controledItem))->scaleTr=tr*((customRectItem*)(this->controledItem))->scaleTr;
		((customRectItem*)(this->controledItem))->translationTr=tr0*((customRectItem*)(this->controledItem))->translationTr;
		((customRectItem*)(this->controledItem))->updatePoints();
		QGraphicsEllipseItem::mouseMoveEvent(event);
	}
/******************************************************************************************************************************************/
BottomLeftPoint::BottomLeftPoint(qreal x,qreal y,QGraphicsItem* item):QGraphicsEllipseItem(-5,-5,10,10),controledItem(item)
{
	this->setPos(x,y);
	this->setBrush(QBrush(QColor(0,0,0)));
	this->setFlag(QGraphicsEllipseItem::ItemIsMovable);
	this->setFlag(QGraphicsItem::ItemIsSelectable);
}
QGraphicsItem* BottomLeftPoint::getControlledItem()
{
	return this->controledItem;
}
void BottomLeftPoint::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
	{
		QGraphicsEllipseItem::mouseDoubleClickEvent(event);
	}
void BottomLeftPoint::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
	{
		QPointF p=this->pos();
		QPointF mouse=this->pos();
		mouse=this->controledItem->mapFromScene(mouse);
		QPointF bp=this->controledItem->pos();
	    double nx=((customRectItem*)(this->controledItem))->trp.x()-mouse.x();
		double ny=mouse.y();
		if(nx<0.1)
			nx=abs(nx)/nx*1;
		if(ny<0.1)
			ny=abs(ny)/ny;
		double newxscale=(nx)/((customRectItem*)(this->controledItem))->oriWidth;
		double newyscale=(ny)*(1.0)/((customRectItem*)(this->controledItem))->oriHeight;
		QTransform tr0=QTransform(1,0,0,1,mouse.x(),0);
		QTransform tr=QTransform(newxscale,0,0,newyscale,0,0);
		this->controledItem->setTransform(tr0,true);
		this->controledItem->setTransform(tr,true);
		((customRectItem*)(this->controledItem))->scaleTr=tr*((customRectItem*)(this->controledItem))->scaleTr;
		((customRectItem*)(this->controledItem))->translationTr=tr0*((customRectItem*)(this->controledItem))->translationTr;
		((customRectItem*)(this->controledItem))->updatePoints();
		QGraphicsEllipseItem::mouseMoveEvent(event);
	}
/******************************************************************************************************************************************/
BottomRightPoint::BottomRightPoint(qreal x,qreal y,QGraphicsItem* item):QGraphicsEllipseItem(-5,-5,10,10),controledItem(item)
{
	this->setPos(x,y);
	this->setBrush(QBrush(QColor(0,0,0)));
	this->setFlag(QGraphicsEllipseItem::ItemIsMovable);
	this->setFlag(QGraphicsItem::ItemIsSelectable);
}
QGraphicsItem* BottomRightPoint::getControlledItem()
{
	return this->controledItem;
}
void BottomRightPoint::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
	{
		
		QGraphicsEllipseItem::mouseDoubleClickEvent(event);
	}
void BottomRightPoint::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
	{
		QPointF p=this->pos();
		QPointF mouse=this->pos();
		mouse=this->controledItem->mapFromScene(mouse);
		QPointF bp=this->controledItem->pos();
		double nx=mouse.x();
		double ny=mouse.y();
		if(nx<0.1)
			nx=abs(nx)/nx*1;
		if(ny<0.1)
			ny=abs(ny)/ny;
		double newxscale=nx/((customRectItem*)(this->controledItem))->oriWidth;
		double newyscale=ny/((customRectItem*)(this->controledItem))->oriHeight;
		QTransform tr=QTransform(newxscale,0,0,newyscale,0,0);
		this->controledItem->setTransform(tr,true);
		((customRectItem*)(this->controledItem))->scaleTr=tr*((customRectItem*)(this->controledItem))->scaleTr;
		((customRectItem*)(this->controledItem))->updatePoints();
		QGraphicsEllipseItem::mouseMoveEvent(event);
	}
/****************************************************************************************************************************************************************/
RotationCenterPoint::RotationCenterPoint(qreal x,qreal y,QGraphicsItem* item):QGraphicsEllipseItem(-5,-5,10,10),controledItem(item)
{
	this->setPos(x,y);
	this->setBrush(QBrush(QColor(255,0,0)));
	this->setFlag(QGraphicsEllipseItem::ItemIsMovable);
	this->setFlag(QGraphicsItem::ItemIsSelectable);
}
QGraphicsItem* RotationCenterPoint::getControlledItem()
{
	return this->controledItem;
}
void RotationCenterPoint::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
	{
		QGraphicsEllipseItem::mouseDoubleClickEvent(event);
	}
void RotationCenterPoint::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
	{
	  ((customRectItem*)(this->controledItem))->rcp=((customRectItem*)(this->controledItem))->mapFromScene(this->pos());
		
		QGraphicsEllipseItem::mouseMoveEvent(event);
	}
/**********************************************************************************************************************************************************/
RotationControlPoint::RotationControlPoint(qreal x,qreal y,QGraphicsItem* item):QGraphicsEllipseItem(-5,-5,10,10),controledItem(item)
{
	this->setPos(x,y);
	this->setBrush(QBrush(QColor(255,0,0)));
	this->setFlag(QGraphicsEllipseItem::ItemIsMovable);
	this->setFlag(QGraphicsItem::ItemIsSelectable);
}
QGraphicsItem* RotationControlPoint::getControlledItem()
{
	return this->controledItem;
}
void RotationControlPoint::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
{
	QGraphicsEllipseItem::mouseDoubleClickEvent(event);
}
void RotationControlPoint::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
	{
	    QPointF final=this->pos();
		QPointF ori=((customRectItem*)(this->controledItem))->rconp;
		QPointF c=((customRectItem*)(this->controledItem))->mapToScene(((customRectItem*)(this->controledItem))->rcp);
		QPointF realcenter=((customRectItem*)(this->controledItem))->rcp;
		qreal r;
		qreal thetatg=(final.x()-c.x())/(c.y()-final.y());
		qreal theta=atan(thetatg);
		if(theta>0&&(final.x()-c.x()>0))
			;
		else if(theta>0&&(final.x()-c.x()<0))
			theta+=acos(-1.0);
		else if(theta<0&&(final.x()-c.x()>0))
			theta+=acos(-1.0);
		else if(theta<0&&(final.x()-c.x())>0)
			theta+=2*acos(-1.0);

		else
			;
		if(abs(c.y()-final.y())<1e-3)
			theta=1.5*(acos(-1.0));
		r=theta;
		qreal cosc=cos(r);
		qreal sinc=sin(r);
		QTransform tr1=QTransform(cosc,sinc,-sinc,cosc,0,0);
		QTransform tr0=QTransform(1,0,0,1,-realcenter.x(),-realcenter.y());
		QTransform tr2=QTransform(cosc,sinc,-sinc,cosc,c.x()-c.x()*cosc+c.y()*sinc,c.y()-c.x()*sinc-c.y()*cosc);
		((customRectItem*)(this->controledItem))->rotationTr=tr1;
		((customRectItem*)(this->controledItem))->axisTr=tr0*((customRectItem*)(this->controledItem))->axisTr;
		QPointF axis=((customRectItem*)(this->controledItem))->getAxis();
		QTransform translation=QTransform(1,0,0,1,axis.x(),axis.y());
		((customRectItem*)(this->controledItem))->resetTransform();
		((customRectItem*)(this->controledItem))->setPos(0,0);
		((customRectItem*)(this->controledItem))->setTransform(translation);
		((customRectItem*)(this->controledItem))->setTransform(((customRectItem*)(this->controledItem))->skewTr,true);
		((customRectItem*)(this->controledItem))->setTransform(((customRectItem*)(this->controledItem))->rotationTr,true);
		((customRectItem*)(this->controledItem))->setTransform(((customRectItem*)(this->controledItem))->scaleTr,true);
		((customRectItem*)(this->controledItem))->setTransform(tr0,true);
		((customRectItem*)(this->controledItem))->updatePoints();
		QGraphicsEllipseItem::mouseMoveEvent(event);
	}
/*******************************************************************************************************************************************/
TopCenterPoint::TopCenterPoint(qreal x,qreal y,QGraphicsItem* item):QGraphicsEllipseItem(-5,-5,10,10),controledItem(item)
{
	this->setPos(x,y);
	this->setBrush(QBrush(QColor(0,255,0)));
	this->setFlag(QGraphicsEllipseItem::ItemIsMovable);
	this->setFlag(QGraphicsItem::ItemIsSelectable);
}
QGraphicsItem* TopCenterPoint::getControlledItem()
{
	return this->controledItem;
}
void TopCenterPoint::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
	{
		QGraphicsEllipseItem::mouseDoubleClickEvent(event);
	}
void TopCenterPoint::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
	{
	  //((customRectItem*)(this->controledItem))->rcp=((customRectItem*)(this->controledItem))->mapFromScene(this->pos());
		QPointF mouse=this->pos();
		mouse=((customRectItem*)(this->controledItem))->mapFromScene(mouse);
		//if(abs(mouse.y())>=8)
			//return;
		qreal x=mouse.x()-((customRectItem*)(this->controledItem))->tcp.x();
		qreal y=((customRectItem*)(this->controledItem))->oriHeight;
		qreal tg=x/y;
		if(abs(tg)>4)
			tg=-4*abs(tg)/tg;
		QTransform tr=QTransform(1,0,-tg,1,0,0);
		QTransform tr0=QTransform(1,0,0,1,x,0);
		((customRectItem*)(this->controledItem))->skewTr=tr*((customRectItem*)(this->controledItem))->skewTr;
		((customRectItem*)(this->controledItem))->setTransform(tr0,true);
		((customRectItem*)(this->controledItem))->setTransform(tr,true);
		((customRectItem*)(this->controledItem))->updatePoints();
		QGraphicsEllipseItem::mouseMoveEvent(event);
		//this->setPos(((customRectItem*)(this->controledItem))->mapToScene(((customRectItem*)(this->controledItem))->tcp));
		//this->update();
	}
/******************************************************************************************************************************/
RightCenterPoint::RightCenterPoint(qreal x,qreal y,QGraphicsItem* item):QGraphicsEllipseItem(-5,-5,10,10),controledItem(item)
{
	this->setPos(x,y);
	this->setBrush(QBrush(QColor(0,255,0)));
	this->setFlag(QGraphicsEllipseItem::ItemIsMovable);
	this->setFlag(QGraphicsItem::ItemIsSelectable);
}
QGraphicsItem* RightCenterPoint::getControlledItem()
{
	return this->controledItem;
}
void RightCenterPoint::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
	{
		QGraphicsEllipseItem::mouseDoubleClickEvent(event);
	}
void RightCenterPoint::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
	{
	  //((customRectItem*)(this->controledItem))->rcp=((customRectItem*)(this->controledItem))->mapFromScene(this->pos());
		QPointF mouse=this->pos();
		mouse=((customRectItem*)(this->controledItem))->mapFromScene(mouse);
		qreal x=mouse.y()-((customRectItem*)(this->controledItem))->rcenterp.y();
		qreal y=((customRectItem*)(this->controledItem))->oriWidth;
		qreal tg=x/y;
		if(abs(tg)>999)
			tg=999*abs(tg)/tg;
		QTransform tr=QTransform(1,tg,0,1,0,0);
		//QTransform tr0=QTransform(1,0,0,1,x,0);
		//((customRectItem*)(this->controledItem))->setTransform(tr0,true);
		((customRectItem*)(this->controledItem))->setTransform(tr,true);
		((customRectItem*)(this->controledItem))->skewTr=tr*((customRectItem*)(this->controledItem))->skewTr;
		((customRectItem*)(this->controledItem))->updatePoints();
		QGraphicsEllipseItem::mouseMoveEvent(event);
	}
/******************************************************************************************************************************/
customRectItem::customRectItem(ItemType it,qreal x,qreal y,qreal w,qreal h,QGraphicsScene* s):QGraphicsPathItem(),scene(s),itemtype(it)//,painterpath(p)
{
	switch(it)
	{
	case RectItem:
		this->painterpath=QPainterPath(QPointF(0,0));
		this->painterpath.addRect(0,0,w,h);
		this->setPath(this->painterpath);
		break;
	case EllipseItem:
		this->painterpath=QPainterPath(QPointF(0,0));
		this->painterpath.addEllipse(0,0,w,h);
		this->setPath(this->painterpath);
		break;
	case LineItem:
		this->painterpath=QPainterPath(QPointF(0,0));
		this->painterpath.moveTo(0,0);
		this->painterpath.lineTo(w,h);
		this->setPath(this->painterpath);
		break;
	}
	this->edited=true;
	this->setPos(x-w/2,y-h/2);
	topleftpoint=new TopLeftPoint(x-w/2,y-h/2,this);
	toprightpoint=new TopRightPoint(x+w/2,y-h/2,this);
	bottomleftpoint=new BottomLeftPoint(x-w/2,y+h/2,this);
	bottomrightpoint=new BottomRightPoint(x+w/2,y+h/2,this);
	rotationcenterpoint=new RotationCenterPoint(x,y,this);
	rotationcontrolpoint=new RotationControlPoint(x,y-h,this);
	topcenterpoint=new TopCenterPoint(x,y-h/2,this);
	rightcenterpoint=new RightCenterPoint(x+w/2,y,this);
	this->topleftpoint->controledItem=this;
	this->toprightpoint->controledItem=this;
	this->bottomleftpoint->controledItem=this;
	this->bottomrightpoint->controledItem=this;
	this->rotationcenterpoint->controledItem=this;
	this->rotationcontrolpoint->controledItem=this;
	this->topcenterpoint->controledItem=this;
	this->rightcenterpoint->controledItem=this;
	this->rightcenterpoint->setZValue(this->zValue()+1);
	this->topcenterpoint->setZValue(this->zValue()+1);
	this->rotationcenterpoint->setZValue(this->zValue()+1);
	this->scene->addItem(topleftpoint);
	this->scene->addItem(toprightpoint);
	this->scene->addItem(bottomleftpoint);
	this->scene->addItem(bottomrightpoint);
	this->scene->addItem(rotationcenterpoint);
	this->scene->addItem(rotationcontrolpoint);
	this->scene->addItem(topcenterpoint);
	this->scene->addItem(rightcenterpoint);

	this->setFlag(QGraphicsEllipseItem::ItemIsMovable);
	this->setFlag(QGraphicsItem::ItemIsSelectable);
	//this->currentWidth=this->boundingRect().width();
	//this->currentHeight=this->boundingRect().height();
	this->oriHeight=h;
	this->oriWidth=w;
	xscale=1;
	yscale=1;
	tlp=this->mapFromScene(this->topleftpoint->pos());
	trp=this->mapFromScene(this->toprightpoint->pos());
	blp=this->mapFromScene(this->bottomleftpoint->pos());
	brp=this->mapFromScene(this->bottomrightpoint->pos());;
	rcp=this->mapFromScene(this->rotationcenterpoint->pos());
	rconp=this->mapFromScene(this->rotationcontrolpoint->pos());
	tcp=this->mapFromScene(this->topcenterpoint->pos());
	this->rcenterp=this->mapFromScene(this->rightcenterpoint->pos());
	/*this->topleftpoint->hide();
	this->toprightpoint->hide();
	this->bottomleftpoint->hide();
	this->bottomrightpoint->hide();*/
	this->translationTr=QTransform();
	this->skewTr=QTransform();
	this->scaleTr=QTransform();
	this->rotationTr=QTransform();

}
void customRectItem::updatePoints()
{
	/*QPointF ntlp=(this->transform()).map(tlp);
	QPointF ntlps=this->mapToScene(ntlp);
	QPointF ntrp=(this->transform()).map(trp);
	QPointF ntrps=this->mapToScene(ntrp);
	this->topleftpoint->setPos(ntlps);
	this->toprightpoint->setPos(ntrps);*/
	qreal angel=this->rotation();
	QPointF ntlp=this->mapToScene(this->tlp);
	//QPointF ntlps=(this->transform()).map(ntlp);
	
	QPointF ntrp=this->mapToScene(this->trp);
	//QPointF ntrps=(this->transform()).map(ntrp);
	
	QPointF nblp=this->mapToScene(this->blp);
	
	QPointF nbrp=this->mapToScene(this->brp);
	
	QPointF nrcp=this->mapToScene(this->rcp);
	
	QPointF nrconp=this->mapToScene(this->rconp);

	QPointF ntcp=this->mapToScene(this->tcp);
	QPointF nrcep=this->mapToScene(this->rcenterp);
	this->rotationcenterpoint->setPos(nrcp);
	this->bottomrightpoint->setPos(nbrp);
	this->bottomleftpoint->setPos(nblp);
	this->toprightpoint->setPos(ntrp);
	this->topleftpoint->setPos(ntlp);
	this->rotationcontrolpoint->setPos(nrconp);
	this->topcenterpoint->setPos(ntcp);
	this->rightcenterpoint->setPos(nrcep);
} 
void customRectItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
	this->updatePoints();
	QGraphicsPathItem::mousePressEvent(event);
}

void customRectItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{
	this->updatePoints();
	QGraphicsPathItem::mouseMoveEvent(event);
}
QVariant customRectItem::itemChange(GraphicsItemChange change,const QVariant& value)
{
	/*bool s=this->isSelected();
	if(change==GraphicsItemChange::ItemSelectedChange&&s)
	{
		if(!this->edited)
			this->hidePoints();
	}
	if(change==GraphicsItemChange::ItemSelectedChange&&!s)
	{
		this->showPoints();
	}*/
     return QGraphicsPathItem::itemChange(change, value);
}
void customRectItem::hidePoints()
{
	this->topleftpoint->hide();
	this->toprightpoint->hide();
	this->bottomleftpoint->hide();
	this->bottomrightpoint->hide();
	this->rotationcenterpoint->hide();
	this->rotationcontrolpoint->hide();
	this->topcenterpoint->hide();
	this->rightcenterpoint->hide();
}
void customRectItem::showPoints()
{
	this->topleftpoint->show();
	this->toprightpoint->show();
	this->bottomleftpoint->show();
	this->bottomrightpoint->show();
	this->rotationcenterpoint->show();
	this->rotationcontrolpoint->show();
	this->topcenterpoint->show();
	this->rightcenterpoint->show();
}